package com.dimong.loan.sdk.utils;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class ImageUtils {

    public static final String TAG = "ImageUtils";

    @SuppressWarnings("deprecation")
    public static Drawable loadActionBarIcon(Context context, int res) {
        Drawable d = null;
        try {
            Bitmap bmp = BitmapFactory.decodeResource(context.getResources(),
                    res);
            d = new BitmapDrawable(bmp);
            d = resizeActionIcon(d);
        } catch (Exception e) {

        }
        return d;
    }

    private static Drawable resizeActionIcon(Drawable drawable) {
        int heightBase = UIUtils.dipToPx(24);
        int height = (int) (heightBase * UIUtils.getDensity());
        Drawable d = ImageUtils.zoomDrawable(drawable, height, height);
        return d;
    }

    public static Bitmap getBitmapByAssets(Context context, String path) {
        Bitmap bitmap = null;
        InputStream in = null;
        try {
            in = context.getResources().getAssets().open(path);
            bitmap = BitmapFactory.decodeStream(in);
        } catch (Exception e) {

        } finally {
            try {
                in.close();
            } catch (Exception ex) {

            }
        }
        return bitmap;
    }

    public static Bitmap roundedCornerBitmap(Bitmap bitmap, float radis) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        // final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = radis;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(Color.WHITE);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }

    public static Bitmap blackWhiteBmp(Bitmap bmp) {
        // black and white

        int width = bmp.getWidth();
        int height = bmp.getHeight();

        ColorMatrix matrix = new ColorMatrix();
        float[] src = {
                0.308F, 0.609F, 0.082F, 0, 0,
                0.308F, 0.609F, 0.082F, 0, 0,
                0.308F, 0.609F, 0.082F, 0, 0,
                0, 0, 0, 1, 0
        };
        matrix.set(src);
        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
        Paint p = new Paint();
        p.setColorFilter(filter);
        Bitmap colorBmp = Bitmap.createBitmap(width, height, bmp.getConfig());
        Canvas c = new Canvas(colorBmp);
        c.drawBitmap(bmp, 0, 0, p);
        return colorBmp;
    }

    public static Bitmap rotateBmp(Bitmap bmp, int angle) {

        int width = bmp.getWidth();
        int height = bmp.getHeight();
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        return Bitmap.createBitmap(bmp, 0, 0, width, height, matrix, true);

    }

    public static Bitmap flipBmp(Bitmap bmp, int mode) {
        // mode 1: h, 2:v

        int width = bmp.getWidth();
        int height = bmp.getHeight();
        Matrix matrix = new Matrix();
        Matrix temp = new Matrix();
        float[] mirrorY = {-1, 0, 0, 0, 1, 0, 0, 0, 1};
        temp.setValues(mirrorY);
        matrix.postConcat(temp);
        if (mode == 2) {
            matrix.setRotate(180, width / 2, height / 2);
        }
        return Bitmap.createBitmap(bmp, 0, 0, width, height, matrix, true);
    }

    public static Bitmap matrixBmp(Bitmap bmp, int margin) {

        int width = bmp.getWidth();
        int height = bmp.getHeight();
        int px = UIUtils.dipToPx(margin);
        Matrix matrix = new Matrix();
        if (width > UIUtils.getWidth() - px) {
            float scale = ((float) (UIUtils.getWidth() - px) / width);
            matrix.postScale(scale, scale);
        } else {
            matrix.postScale(1, 1);
        }
        return Bitmap.createBitmap(bmp, 0, 0, width, height, matrix, true);
    }

    public static byte[] readFileImage(String filename) throws Exception {
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filename));
        int len = bufferedInputStream.available();
        byte[] bytes = new byte[len];
        int r = bufferedInputStream.read(bytes);
        if (len != r) {
            bytes = null;
        }
        bufferedInputStream.close();
        return bytes;
    }

    public static Bitmap blurBmp(Bitmap bmp, int Blur) {

        int pixels[] = new int[bmp.getWidth() * bmp.getHeight()];
        int pixelsRawSource[] = new int[bmp.getWidth() * bmp.getHeight() * 3];
        int pixelsRawNew[] = new int[bmp.getWidth() * bmp.getHeight() * 3];
        bmp.getPixels(pixels, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight());

        for (int k = 1; k <= Blur; k++) {

            for (int i = 0; i < pixels.length; i++) {
                pixelsRawSource[i * 3 + 0] = Color.red(pixels[i]);
                pixelsRawSource[i * 3 + 1] = Color.green(pixels[i]);
                pixelsRawSource[i * 3 + 2] = Color.blue(pixels[i]);
            }

            int CurrentPixel = bmp.getWidth() * 3 + 3;
            for (int i = 0; i < bmp.getHeight() - 3; i++) {
                for (int j = 0; j < bmp.getWidth() * 3; j++) {
                    CurrentPixel += 1;

                    int sumColor = 0;
                    sumColor = pixelsRawSource[CurrentPixel - bmp.getWidth()
                            * 3];
                    sumColor = sumColor + pixelsRawSource[CurrentPixel - 3];
                    sumColor = sumColor + pixelsRawSource[CurrentPixel + 3];
                    sumColor = sumColor + pixelsRawSource[CurrentPixel + bmp.getWidth() * 3];
                    pixelsRawNew[CurrentPixel] = Math.round(sumColor / 4);
                }
            }

            for (int i = 0; i < pixels.length; i++) {
                pixels[i] = Color.rgb(pixelsRawNew[i * 3 + 0], pixelsRawNew[i * 3 + 1], pixelsRawNew[i * 3 + 2]);
            }
        }

        Bitmap bmpReturn = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.ARGB_8888);
        bmpReturn.setPixels(pixels, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight());

        return bmpReturn;

    }

    public static Bitmap colorMatrixBmp(Bitmap bmp, float[] matrixSrc) {

        int width = bmp.getWidth();
        int height = bmp.getHeight();

        ColorMatrix matrix = new ColorMatrix();
        matrix.set(matrixSrc);
        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
        Paint p = new Paint();
        p.setColorFilter(filter);
        Bitmap colorBmp = Bitmap.createBitmap(width, height, bmp.getConfig());
        Canvas c = new Canvas(colorBmp);
        c.drawBitmap(bmp, 0, 0, p);
        return colorBmp;
    }

    public static Bitmap zoomImage(Bitmap bmp, double newWidth, double newHeight) {
        float width = bmp.getWidth();
        float height = bmp.getHeight();
        Matrix matrix = new Matrix();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(bmp, 0, 0, (int) width, (int) height, matrix, true);
        return bitmap;
    }

    public static Bitmap drawableToBitmap(Drawable drawable) {

        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();

        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;

        Bitmap bitmap = Bitmap.createBitmap(w, h, config);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        drawable.draw(canvas);
        return bitmap;
    }

    @SuppressWarnings("deprecation")
    public static Drawable zoomDrawable(Drawable drawable, int w, int h) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        Bitmap oldbmp = drawableToBitmap(drawable);
        Matrix matrix = new Matrix();
        float sx = ((float) w / width);
        float sy = ((float) h / height);
        matrix.postScale(sx, sy);
        Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true);
        return new BitmapDrawable(newbmp);
    }

    public static String getImageAbsolutePath(Context context, Uri imageUri) {
        if (context == null || imageUri == null) {
            return null;
        }
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, imageUri)) {
            if (isExternalStorageDocument(imageUri)) {
                String docId = DocumentsContract.getDocumentId(imageUri);
                String[] split = docId.split(":");
                String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            } else if (isDownloadsDocument(imageUri)) {
                String id = DocumentsContract.getDocumentId(imageUri);
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            } else if (isMediaDocument(imageUri)) {
                String docId = DocumentsContract.getDocumentId(imageUri);
                String[] split = docId.split(":");
                String type = split[0];
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }
                String selection = MediaStore.Images.Media._ID + "=?";
                String[] selectionArgs = new String[]{split[1]};
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        } else if ("content".equalsIgnoreCase(imageUri.getScheme())) {
            if (isGooglePhotosUri(imageUri))
                return imageUri.getLastPathSegment();
            return getDataColumn(context, imageUri, null, null);
        } else if ("file".equalsIgnoreCase(imageUri.getScheme())) {
            return imageUri.getPath();
        }
        return null;
    }


    /**
     * File Uri都可以转换成Content Uri
     * 多媒体相关的文件才可以。
     * @param context
     * @param imageFile
     * @return
     */
    public static Uri getImageContentUri(Context context, File imageFile) {
        String filePath = imageFile.getAbsolutePath();
        Cursor cursor = context.getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                new String[] { MediaStore.Images.Media._ID },
                MediaStore.Images.Media.DATA + "=? ",
                new String[] { filePath }, null);

        if (cursor != null && cursor.moveToFirst()) {
            int id = cursor.getInt(cursor
                    .getColumnIndex(MediaStore.MediaColumns._ID));
            Uri baseUri = Uri.parse("content://media/external/images/media");
            return Uri.withAppendedPath(baseUri, "" + id);
        } else {
            if (imageFile.exists()) {
                ContentValues values = new ContentValues();
                values.put(MediaStore.Images.Media.DATA, filePath);
                return context.getContentResolver().insert(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            } else {
                return null;
            }
        }
    }

    public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        String column = MediaStore.Images.Media.DATA;
        String[] projection = {column};
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    /**
     * 同比压缩图片
     * @param path
     * @param reqSize
     * @return
     */
    public static Bitmap getSmallBitmap(String path, int reqSize) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        int scale = 1;

        while (true) {
            if (options.outWidth <= reqSize || options.outHeight <= reqSize) {
                break;
            } else {
                options.outWidth = options.outWidth / 2;
                options.outHeight = options.outHeight / 2;
                scale++;
            }
        }
        BitmapFactory.Options newoptions = new BitmapFactory.Options();
        newoptions.inSampleSize = scale;
//        newOpts.inPreferredConfig = Config.ARGB_8888;//该模式是默认的,可不设
//        newOpts.inPurgeable = true;// 同时设置才会有效
//        newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
        return BitmapFactory.decodeFile(path, newoptions);
    }


    /**
     * 按大小压缩质量
     * @param image
     * @param
     * @return
     */
    public static Bitmap compressBmpFromBmp(Bitmap image,int options,boolean isPng) {
        return compressBmpFromBmp(image,options,isPng,true);
    }

    /**
     * 按大小压缩质量
     * @param image
     * @param
     * @return
     */
    public static Bitmap compressBmpFromBmp(Bitmap image,int options,boolean isPng,boolean isRecyle) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Bitmap.CompressFormat foramt = Bitmap.CompressFormat.JPEG;
        if(isPng){
            foramt = Bitmap.CompressFormat.PNG;
        }
        image.compress(foramt, options, baos);
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
        if(image != null && isRecyle){
            image.recycle();
        }
        return bitmap;
    }

    /**
     * 基于质量的压缩算法， 此方法未 解决压缩后图像失真问题
     * <br> 可先调用比例压缩适当压缩图片后，再调用此方法可解决上述问题
     * @param bitmap
     * @param isPng
     * @param maxBytes 压缩后的图像最大大小 单位为byte
     * @return
     */
    public final static Bitmap compressBitmap(Bitmap bitmap, long maxBytes,boolean isPng) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Bitmap.CompressFormat foramt = Bitmap.CompressFormat.JPEG;
            if(isPng){
                foramt = Bitmap.CompressFormat.PNG;
            }
            bitmap.compress(foramt, 100, baos);
            int options = 90;
            while (baos.toByteArray().length > maxBytes) {
                if(options > 10) {
                    baos.reset();
                    bitmap.compress(foramt, options, baos);
                    options -= 10;
                }else{
                    break;
                }
            }
            byte[] bts = baos.toByteArray();
            Bitmap bmp = BitmapFactory.decodeByteArray(bts, 0, bts.length);
            baos.close();
            return bmp;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

    /**
     * get the orientation of the bitmap {@link android.media.ExifInterface}
     * 获取拍照图片角度
     * @param path
     * @return
     */
    public final static int getDegress(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * rotate the bitmap
     * 旋转图片
     * @param bitmap
     * @param degress
     * @return
     */
    public static Bitmap rotateBitmap(Bitmap bitmap, int degress) {
        if (bitmap != null) {
            Matrix m = new Matrix();
            m.postRotate(degress);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
            return bitmap;
        }
        return bitmap;
    }

    /**
     * 压缩资源图片，并返回图片对象
     * @param res {@link android.content.res.Resources}
     * @param resID
     * @param reqsW
     * @param reqsH
     * @return
     */
    public final static Bitmap compressBitmap(Resources res, int resID, int reqsW, int reqsH) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resID, options);
        options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resID, options);
    }

    /**
     * caculate the bitmap sampleSize
     * @return
     */
    public final static int caculateInSampleSize(BitmapFactory.Options options, int rqsW, int rqsH) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (rqsW == 0 || rqsH == 0) return 1;
        if (height > rqsH || width > rqsW) {
            final int heightRatio = Math.round((float) height/ (float) rqsH);
            final int widthRatio = Math.round((float) width / (float) rqsW);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }

    /**
     * 保存图片到文件
     * @param bit
     * @param path
     * @param isPng
     * @return
     */
    public static boolean saveBitmapToFile(Bitmap bit,String path,boolean isPng) {
        File f = new File(path);
        if (f.exists()) {
            f.delete();
        }
        try {
            Bitmap.CompressFormat foramt = Bitmap.CompressFormat.JPEG;
            if(isPng){
                foramt = Bitmap.CompressFormat.PNG;
            }
            FileOutputStream out = new FileOutputStream(f);
            bit.compress(foramt, 100, out);
            out.flush();
            out.close();
            return true;
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 保存图片到文件
     * @param bit
     * @param path
     * @param isPng
     * @return
     */
    public static boolean saveBitmapToFile(Bitmap bit,String path,int options,boolean isPng) {
        File f = new File(path);
        if (f.exists()) {
            f.delete();
        }
        try {
            Bitmap.CompressFormat foramt = Bitmap.CompressFormat.JPEG;
            if(isPng){
                foramt = Bitmap.CompressFormat.PNG;
            }
            FileOutputStream out = new FileOutputStream(f);
            bit.compress(foramt, options, out);
            out.flush();
            out.close();
            return true;
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }

    }



}
